package com.jsmile.cloud.msgcenter.msg.controller;

import javax.validation.Valid;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jsmile.cloud.authc.api.enums.ClientSourceEnum;
import com.jsmile.cloud.msgcenter.api.enums.MsgCodeEnum;
import com.jsmile.cloud.msgcenter.api.exception.MsgException;
import com.jsmile.cloud.msgcenter.api.to.login.WxLoginTo;
import com.jsmile.cloud.msgcenter.pay.manage.WxLoginManage;
import com.jsmile.cloud.msgcenter.web.config.PayConfig;
import com.jsmile.mail.security.handler.JsmileContext;
import com.jsmile.mall.api.JSmileResult;
import com.jsmile.mall.api.annotation.CurrentContext;
import com.jsmile.mall.api.constants.JSmileConstant;
import com.jsmile.mall.api.enums.LogTypeEnum;
import com.jsmile.mall.log.annotation.JsmileLog;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;

/**
 * @author 龚亮
 * @version 1.0
 * @desc 微信授权控制器
 * @date 2018年08月25日 04:57:24
 */
@RestController
@RequestMapping("/wx")
@Api(tags = "微信授权")
@Slf4j
@AllArgsConstructor
public class WxLoginController {

    private final WxLoginManage wxLoginManage;

    @PostMapping("/login")
    @JsmileLog(title = "消息中心->微信小程序授权获取用户信息", type = LogTypeEnum.INSERT, systemId = JSmileConstant.SystemId.MSG_CENTER)
    public JSmileResult login(@RequestBody @Valid WxLoginTo wxLoginTo, @CurrentContext JsmileContext context) {
        context.setClientSource(ClientSourceEnum.WX_MP.getValue());
        final WxMaService wxService = PayConfig.getMaService(wxLoginTo.getAppid());
        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(wxLoginTo.getCode());
            // 解密用户信息
            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(session.getSessionKey(), wxLoginTo.getEncryptedData(), wxLoginTo.getIv());
            WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), wxLoginTo.getEncryptedData(), wxLoginTo.getIv());
            log.info("小程序用户信息：{},手机号码：{}", userInfo, phoneNoInfo);
            return wxLoginManage.wxLogin(session.getOpenid(), null, session.getUnionid(), wxLoginTo.getUserInfo().getNickName(), wxLoginTo.getUserInfo().getProvince(),
                wxLoginTo.getUserInfo().getCity(), wxLoginTo.getUserInfo().getGender(), wxLoginTo.getUserInfo().getAvatarUrl(), context);
        } catch (Exception e) {
            log.info("微信小程序信息获取失败：{}", ExceptionUtils.getStackTrace(e));
            throw new MsgException(MsgCodeEnum.WX_INFO_ERROR);
        }
    }

    @PostMapping("/mp/login")
    @JsmileLog(title = "消息中心->微信公众号授权获取用户信息", type = LogTypeEnum.INSERT, systemId = JSmileConstant.SystemId.MSG_CENTER)
    public JSmileResult mpLogin(@RequestBody @Valid WxLoginTo wxLoginTo, @CurrentContext JsmileContext context) {
        context.setClientSource(ClientSourceEnum.WX.getValue());
        final WxMpService wxService = PayConfig.getMpService(wxLoginTo.getAppid());
        try {
            WxMpOAuth2AccessToken accessToken = wxService.oauth2getAccessToken(wxLoginTo.getCode());
            WxMpUser user = wxService.oauth2getUserInfo(accessToken, null);
            return wxLoginManage.wxLogin(user.getOpenId(), user.getOpenId(), user.getUnionId(), user.getNickname(), user.getProvince(), user.getCity(),
                (null == user.getSex() ? null : user.getSex().toString()), user.getHeadImgUrl(), context);
        } catch (Exception e) {
            log.info("微信公众号信息获取失败：{}", ExceptionUtils.getStackTrace(e));
            throw new MsgException(MsgCodeEnum.WX_INFO_ERROR);
        }
    }

}
